using System.Diagnostics;
using System.Windows.Forms;
using Mbs.Elements;
using Mbs.Modularity.AddIns;
using Mbs.ComponentModel.Container;

namespace Mbs.Windows.Elements.Builders
{
    static class ToolStripItemHelper
    {
        public static void Initialize(this ToolStripItem toolStripItem, IAddInItem addInItem)
        {
            toolStripItem.RightToLeft = RightToLeft.Inherit;
            toolStripItem.Name = addInItem.Path;

            if (addInItem.Properties.Contains("Enabled"))
                toolStripItem.Enabled = addInItem.Properties.Get<bool>("Enabled", true);
            if (addInItem.Properties.Contains("Visible"))
                toolStripItem.Visible = addInItem.Properties.Get<bool>("Visible", true);
        }

        public static void SetToolTip(this ToolStripItem item, IAddInItem addInItem)
        {
            if (addInItem.Properties.Contains("ToolTip"))
                item.ToolTipText = addInItem.Properties.Get<string>("ToolTip").StringResource();
        }
    }

    

    public class ToolStripItemBuilder<TToolStripItem> : ElementBuilder where TToolStripItem : ToolStripItem, new()
    {
        [Inject]
        public IElementService ElementService { protected get; set; }

        protected IAddInItem AddInItem { get; private set; }

        protected virtual TToolStripItem CreateItem(IAddInItem addInItem)
        {
            return new TToolStripItem();
        }

        public override object Create(object caller, IAddInItem addinItem)
        {
            Debug.Assert(addinItem != null, "addinItem == null");
            Debug.Assert(!string.IsNullOrEmpty(addinItem.Type), "addinItem.Type == null");

            AddInItem = addinItem;

            var item = CreateItem(addinItem);

            return item;
        }

        public override void InitInstance(object caller, IAddInItem element, System.Collections.Generic.List<object> subItems, object instance)
        {
            var toolStripItem = instance as TToolStripItem;
            if (toolStripItem != null && toolStripItem.Owner == null)
                OnInitInstance(caller, element, subItems, toolStripItem);
        }

        protected virtual void OnInitInstance(object caller, IAddInItem element, System.Collections.Generic.List<object> subItems, ToolStripItem toolStripItem)
        {
            if (toolStripItem != null)
                BindCommand(element, toolStripItem, "Click");
        }


        protected void BindCommand(IAddInItem element, ToolStripItem item, string @event)
        {
            SetToolStripItemOwner(item, element);
            if (!string.IsNullOrEmpty(element.Command) && !string.IsNullOrEmpty(@event))
                Disposes.Add(element.Command.Attach(item, @event));
        }

        private void AddChildItem(ToolStripItemCollection items, ToolStripItem item, ToolStripItem brother)
        {
            var index = brother != null ?  items.IndexOf(brother) : -1;
            if (index != -1)
                items.Insert(index + 1, item);
            else
                items.Add(item);
        }

        private bool PopulateParentAndBrother(ToolStripItem item, IAddInNode element)
        {
            var parent = ServiceLocator.Current.Get(element.ParentPath);

            if (parent == null)
                return false;

            var toolstrip = parent as ToolStrip;
            ToolStripItem brother = null;

            var hasOldBrother = !string.IsNullOrEmpty(element.Properties.Get<string>("OldBrother"));
            if(hasOldBrother)
                brother = ServiceLocator.Current.Get(element.ParentPath + "/" + element.Properties.Get<string>("OldBrother")) as ToolStripItem;

            if (toolstrip != null)
            {
                AddChildItem(toolstrip.Items, item, brother);
                return true;
            }

            var dropDown = parent as ToolStripDropDownItem;
            if (dropDown != null)
            {
                AddChildItem(dropDown.DropDownItems, item, brother);
                return true;
            }
            return false;

        }

        protected void SetToolStripItemOwner(ToolStripItem item, IAddInNode element)
        {
            if (PopulateParentAndBrother(item, element))
                return;

            var parent = ServiceLocator.Current.Get(element.ParentPath);
            if (parent != null && parent is ToolStrip)
                item.Owner = parent as ToolStrip;
            else
                SetToolStripItemOwner(item, AddInTree.Get(element.ParentPath));
        }

    }
}
